package com.ww.springboot.boot.thread.study.base.cyclicbarrier;

import java.util.Random;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 描述： CyclicBarrier:所有任务相互等待 直到所有的任务全部完成-- 可以重置计数值
 * CountDownLatch:有一个显示锁等待全部任务完成 -- 等待节点控制更灵活
 * <p>
 * CyclicBarrier: 使用重入锁的条件队列 计数未到则条件等待 计数到达则全部一起唤醒
 *
 * @author wanwei
 * @since 2021-10-20 17:46
 */
public class Demo {
    public static void main(String[] args) {
        CyclicBarrier cyclicBarrier = new CyclicBarrier(3);
        cyclicBarrier.reset();
        ExecutorService executorService = Executors.newFixedThreadPool(3);
        try {
            executorService.execute(new Runner(cyclicBarrier, "张三"));
            executorService.execute(new Runner(cyclicBarrier, "李四"));
            executorService.execute(new Runner(cyclicBarrier, "王五"));
        } finally {
            executorService.shutdown();
        }
    }

    static class Runner implements Runnable {
        private String name;
        private CyclicBarrier cyclicBarrier;

        public Runner(CyclicBarrier cyclicBarrier, String name) {
            this.name = name;
            this.cyclicBarrier = cyclicBarrier;
        }

        @Override
        public void run() {
            try {
                Thread.sleep(1000 * new Random().nextInt(5));
                System.out.println(name + "-" + Thread.currentThread().getName() + "已经准备好");
                //阻塞子线程
                cyclicBarrier.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
            System.err.println(Thread.currentThread().getName() + "出发！！");
        }

    }
}
